<?php
namespace app\common\service\impl;
use app\common\service\AccountService;
use app\common\service\RentService;
use app\common\model\PartDetails;
use think\facade\Log;
use app\common\model\Account;
use app\common\model\AccountList;
class AccountServiceImpl implements AccountService
{
    private $rentService;
    private $account;
    private $accountList;
    
    public function __construct(RentService $rentService,Account $account,AccountList $accountList)
    {
        $this->rentService = $rentService;
        $this->account = $account;
        $this->accountList = $accountList;
    }
    
    public function index(array $where,int $page,int $length)
    {
        
        
        try {
            $model = Account::with('user.agency,accountList')->where($where)->order('id', 'desc')
            ->paginate($length,false,[
                'type'     => 'bootstrap',
                'var_page' => 'page',
                'page'=>$page,
            ]);
            
        } catch (\Exception $e) {
            Log::record('账单列表:'.$e->getMessage(),'error');
            return false;
        }
        return $model;
    }
    
    public function details(int $id)
    {
        try {
            $data = Account::get($id,['accountList'=>['rent','brand'],'user']);
            
        } catch (\Exception $e) {
            Log::record('账单详情:'.$e->getMessage(),'error');
            return false;
        }
        return $data;
    }

  public function save(Array $data){
     $stringTime = date("Y-m-dH:i:s",time());
     $tradeNo = str_replace(["-",":"],'',$stringTime);
     $tradeNo.= $data['user_id'];
     $tradeNo.= mt_rand(100000, 999999);
     $tradeNo.= $data['user_id'];
      
     $nowTime = time();
     $accountTime = date('j',$nowTime)>=25?mktime(0, 0, 0, date("m",$nowTime) +1 , 25, date("Y",$nowTime)):mktime(0, 0, 0, date("m",$nowTime) , 25, date("Y",$nowTime));
    $nextAccountTime =  date('j',$nowTime)>=25?mktime(0, 0, 0, date("m",$nowTime) +2 , 25, date("Y",$nowTime)):mktime(0, 0, 0, date("m",$nowTime)+1 , 25, date("Y",$nowTime));
     
     $account = $this->account->where(['user_id'=>$data['user_id'],'repayment_time'=>$accountTime])->where('charge_status','in','2,4')->find();
    
     $accountData = [];
     $nextAccount = [];
    
    if($account){
       $data['account_id'] = $account['id'];
      if($data['type'] == 1){
          if($account['deserve'] == 0){
              if($account['reduce'] >= $data['money']){
                  $accountData['deserve'] = 0;
                  $accountData['reduce'] = $account['reduce'] - $data['money'];
              }else{
                  
                  $accountData['deserve'] = $data['money'] - $account['reduce'];
                  $accountData['reduce'] = 0;
              }
              $accountData['amount'] = $account['amount'] + $data['money'];
              $accountData['increase'] = $account['increase'] + $data['money'];

          }else{
              $accountData = [
                  'amount'=>$account['amount'] + $data['money'],
                  'deserve'=>$account['deserve'] + $data['money'],
                  'increase'=>$account['increase'] + $data['money']
              ];
          }

      }elseif ($data['type'] == 2) {
         
          if($account['deserve'] > $data['money']){
              $accountData = [
                  'deserve'=>$account['deserve'] - $data['money'],
                  'reduce'=>0,
                  'charge_status'=>4
              ];
              
          }elseif ($account['deserve'] < $data['money']){
              $accountData = [
                  'deserve'=>0,
                  'reduce'=>$data['money'] - $account['deserve'],
                  'charge_status'=>1
              ];
              
              $nextAccount = [
                  'user_id'=>$data['user_id'],
                  'trade_no' =>$tradeNo,
                  'amount'=>0,
                  'reduce'=>$data['money'] - $account['deserve'],
                  'deserve'=>0,
                  'repayment_time'=>$nextAccountTime,
                  'repayment_date'=>date("Y-m-d",$nextAccountTime),
                  'charge_status'=>2
              ];
              
          }elseif ($account['deserve'] == $data['money']){
              $accountData = [
                  'deserve'=>0,
                  'reduce'=>0,
                  'charge_status'=>1
              ];
          }
        
      }elseif ($data['type'] == 3) {
          if($account['deserve'] > $data['money']){
              $accountData = [
                  'deserve'=>$account['deserve'] - $data['money'],
                  'actual'=>$data['money'],
                  'actual_time'=>time(),
                  'charge_status'=>4
              ];
              
          }elseif ($account['deserve'] < $data['money']){
              $accountData = [
                  'deserve'=>0,
                  'actual'=>$data['money'],
                  'actual_time'=>time(),
                  'charge_status'=>1
              ];
              
              $nextAccount = [
                  'user_id'=>$data['user_id'],
                  'trade_no' =>$tradeNo,
                  'amount'=>0,
                  'deserve'=>0,
                  'reduce'=>$data['money'] - $account['deserve'],
                  'actual'=>$data['money'] - $account['deserve'],
                  'actual_time'=>time(),
                  'repayment_time'=>$nextAccountTime,
                  'repayment_date'=>date("Y-m-d",$nextAccountTime),
                  'charge_status'=>2
              ];
              
          }elseif ($account['deserve'] == $data['money']){
              $accountData = [
                  'deserve'=>0,
                  'actual'=>$data['money'],
                  'actual_time'=>time(),
                  'charge_status'=>1
              ];
              
          }
        
      }

    }else{
        
        if($data['type'] == 1){
            $nextAccount = [
                'user_id'=>$data['user_id'],
                'trade_no' =>$tradeNo,
                'amount'=>$data['money'],
                'deserve'=>$data['money'],
                'increase'=>$data['money'],
                'repayment_time'=>$accountTime,
                'repaymentTime'=>date("Y-m-d",$accountTime),
                'charge_status'=>2
            ];
            
        }elseif ($data['type'] == 2){
            $nextAccount = [
                'user_id'=>$data['user_id'],
                'trade_no' =>$tradeNo,
                'amount'=>0,
                'deserve'=>0,
                'reduce'=>$data['money'],
                'repayment_time'=>$accountTime,
                'repaymentTime'=>date("Y-m-d",$accountTime),
                'charge_status'=>2
            ];
            
        }elseif ($data['type'] == 3){
            $nextAccount = [
                'user_id'=>$data['user_id'],
                'trade_no' =>$tradeNo,
                'amount'=>0,
                'deserve'=>0,
                'actual'=>$data['money'],
                'actual_time'=>time(),
                'repayment_time'=>$accountTime,
                'repaymentTime'=>date("Y-m-d",$accountTime),
                'charge_status'=>2
            ];
        }
        
        
    }
    
    if(!empty($accountData)){
        try {
            $this->account->save($accountData,['id'=>$account['id']]);
            
        } catch (\Exception $e) {
            Log::record('账单更新:'.$e->getMessage(),'error');
            return false;
        }
    }
    
    if(!empty($nextAccount)){
        $nextAccountModel = $this->account->where(['user_id'=>$data['user_id'],'repayment_time'=>$nextAccountTime])->where('charge_status','in','2,4')->find();
        if($nextAccountModel){
            $nextAccount['reduce'] = $nextAccountModel['reduce'] + $data['money'] - $account['deserve'];
            $nextAccount['actual'] = $nextAccountModel['actual'] + $data['money'] - $account['deserve'];
            $this->account->update($nextAccount,['id'=>$nextAccountModel['id']]);
        }else{
            
            try {
                $accountModel = $this->account->create($nextAccount);
                $data['account_id'] = $accountModel->id;
            } catch (\Exception $e) {
                Log::record('生成账单:'.$e->getMessage(),'error');
                return false;
            }
        }
    }
    
    try {
        
        $this->accountList->create($data);
        
    } catch (\Exception $e) {
        Log::record('账单详情:'.$e->getMessage(),'error');
        return false;
    }
    
    return true;
    
  }

   
    public function partAccount(String $num)
    {
          $data = $this->rentService->details($num);
          
          if($data){
              $partData = [];
              $accountData = [];
              $accountListData = [];

              $nowTime = time();
              $accountTime = date('j',$nowTime)>=25?mktime(0, 0, 0, date("m",$nowTime) +1 , 25, date("Y",$nowTime)):mktime(0, 0, 0, date("m",$nowTime) , 25, date("Y",$nowTime));
              $accountModel = $this->account->get(['user_id'=>$data['rent']['user_id'],'repayment_time'=>$accountTime]);
              if(empty($accountModel->id)){
                  $stringTime = date("Y-m-dH:i:s",time());
                  $tradeNo = str_replace(["-",":"],'',$stringTime);
                  $tradeNo.= $data['rent']['user_id'];
                  $tradeNo.= mt_rand(100000, 999999);
                  $tradeNo.= $data['rent']['user_id'];
                  $accountData = ['user_id'=>$data['rent']['user_id'],'trade_no'=>$tradeNo,'deserve'=>0,'amount'=>0,'repayment_time'=>$accountTime,'charge_status'=>2,'reduce'=>0];
                  $accountModel = $this->account->create($accountData);
                  $accountData['id'] = $accountModel->id;
              }else{
                  $accountData = ['id'=>$accountModel->id,'user_id'=>$data['rent']['user_id'],'trade_no'=>$accountModel->trade_no,'amount'=>$accountModel->amount,'deserve'=>$accountModel->deserve,'repayment_time'=>$accountModel->repayment_time,'charge_status'=>$accountModel->charge_status];
              }
              foreach ($data['contract'] as $value){
                  for ($i = 1,$j=0; $i <= $value['period']; $i++,$j++) {
                      
                       $startTime= 0;
                       $differDay = 0;
                       $endTime = 0;
                       $type = 0;
                       $repayMentTime = 0;
                       $time = 0;
                      if($data['rent']['charge_type'] == 1){
                          $startTime = mktime(0, 0, 0, date("m",$value['dispatch_time']) +$j , date("d",$value['dispatch_time']), date("Y",$value['dispatch_time']));  
                          $endTime = mktime(0, 0, 0, date("m",$value['dispatch_time']) +$i , date("d",$value['dispatch_time']), date("Y",$value['dispatch_time']));
                          $type = 2;
                          $time = date('j',$value['dispatch_time']);
                          if($time>=25){
                              $repayMentTime = mktime(0, 0, 0, date("m",$value['dispatch_time']) +$i , 25, date("Y",$value['dispatch_time']));
                          }else{
                              $repayMentTime = mktime(0, 0, 0, date("m",$value['dispatch_time']) +$j , 25, date("Y",$value['dispatch_time']));;
                          }
                          
                      }else{ 
                          if($i == 1){
                              $month = date('t',$value['dispatch_time']);
                              $day = date('j',$value['dispatch_time']);
                              $differDay = $month - $day;
                              $startTime = $value['dispatch_time'];
                              $endTime =  mktime(0, 0, 0, date("m",$value['dispatch_time']) +$j , date("d",$value['dispatch_time']) + $differDay, date("Y",$value['dispatch_time']));
                              $type = 1;
                              if($day>=25){
                                  $repayMentTime = mktime(0, 0, 0, date("m",$value['dispatch_time']) +$i , 25, date("Y",$value['dispatch_time']));
                              }else{
                                  $repayMentTime = mktime(0, 0, 0, date("m",$value['dispatch_time']) +$j , 25, date("Y",$value['dispatch_time']));;
                              }
                              
                          }else{
                              $startTime = mktime(0, 0, 0, date("m",$value['dispatch_time']) +$j , 1, date("Y",$value['dispatch_time']));
                              $repayMentTime = mktime(0, 0, 0, date("m",$value['dispatch_time']) +$j , 25, date("Y",$value['dispatch_time']));
                              if($i == $value['period']){
                                  $endTime =  mktime(0, 0, 0, date("m",$value['dispatch_time'])+$j,date('t',$startTime), date("Y",$value['dispatch_time']));
                                  $lastStartTime = mktime(0, 0, 0, date("m",$value['dispatch_time']) +$i , 1, date("Y",$value['dispatch_time']));
                                  $lastEndTime = mktime(0, 0, 0, date("m",$value['dispatch_time']) +$i ,date("d",$value['dispatch_time']) , date("Y",$value['dispatch_time']));
                                  $lastDifferDay = date('j',$lastEndTime);
                                  $lastRepayTime = mktime(0, 0, 0, date("m",$value['dispatch_time']) +$i , 25, date("Y",$value['dispatch_time']));
                                  
                                  $partData[]= [
                                      'user_id'=>$data['rent']['user_id'],
                                      'contract_no'=>$value['contract_no'],
                                      'car_sn'=>$value['car_sn'],
                                      'vin'=>$value['vin'],
                                      'brand_id'=>$value['brand_id'],
                                      'rent_money'=>$value['rent_money'],
                                      'service_money'=>$value['service_money'],
                                      'part_total'=>$value['period']+1,
                                      'pay_day'=>$i,
                                      'start_time'=>$lastStartTime,
                                      'end_time'=>$lastEndTime,
                                      'repayment_time'=>$lastRepayTime,
                                      'differ_day'=>$lastDifferDay,
                                      'type'=>1,
                                      'charge_status'=>$lastRepayTime>time()?2:1,
                                      'begin_date'=>date('Y-m-d',$lastStartTime),
                                      'finish_date'=>date('Y-m-d',$lastEndTime),
                                      'repayment_date'=>date('Y-m-d',$lastRepayTime)
                                      
                                  ];
                              }else{
                                
                                $endTime =  mktime(0, 0, 0, date("m",$value['dispatch_time']) +$j ,date('t',$startTime), date("Y",$value['dispatch_time']));
                              }
                              $type = 2;
                          }
                          
                      }
                      if($repayMentTime == $accountTime){
                          if($data['rent']['charge_type'] == 1){
                              $accountData['amount'] += $value['rent_money'];
                              $accountData['amount'] += $value['service_money'];
                              $accountData['deserve'] += $value['rent_money'];
                              $accountData['deserve'] += $value['service_money'];
                              $accountData['charge_status'] = 2;
                              
                              $accountListData[] = ['account_id'=>$accountData['id'],'user_id'=>$accountData['user_id'],'name'=>$value['car_sn'],'money'=>$value['rent_money']+$value['service_money'],'type'=>4,'contract_no'=>$value['contract_no'],'brand_id'=>$value['brand_id']];
                              
                          }else{
                              if($type == 1){
                                  $rentMoney = round($value['rent_money']*$differDay/30,2);
                                  $serviceMoney = round($value['service_money']*$differDay/30,2);
                                  $accountData['amount'] += $rentMoney ;
                                  $accountData['amount'] += $serviceMoney;
                                  $accountData['deserve'] += $rentMoney;
                                  $accountData['deserve'] += $serviceMoney;
                                  $accountData['charge_status'] = 2;
                                  
                                  $accountListData[] = [
                                      'account_id'=>$accountData['id'],
                                      'user_id'=>$accountData['user_id'],
                                      'name'=>$value['car_sn'],
                                      'money'=>$rentMoney+$serviceMoney,
                                      'type'=>4,
                                      'contract_no'=>$value['contract_no'],
                                      'brand_id'=>$value['brand_id']
                                      
                                  ];
                              }else{
                                  
                                  $accountData['amount'] += $value['rent_money'];
                                  $accountData['amount'] += $value['service_money'];
                                  $accountData['deserve'] += $value['rent_money'];
                                  $accountData['deserve'] += $value['service_money'];
                                  $accountData['charge_status'] = 2;
                                  
                                  $accountListData[] = ['account_id'=>$accountData['id'],'user_id'=>$accountData['user_id'],'name'=>$value['car_sn'],'money'=>$value['rent_money']+$value['service_money'],'type'=>4,'contract_no'=>$value['contract_no'],'brand_id'=>$value['brand_id']];
                              }
                          }
                          
                      }
                      $partData[]= [
                          'user_id'=>$data['rent']['user_id'],
                          'contract_no'=>$value['contract_no'],
                          'car_sn'=>$value['car_sn'],
                          'vin'=>$value['vin'],
                          'brand_id'=>$value['brand_id'],
                          'rent_money'=>$value['rent_money'],
                          'service_money'=>$value['service_money'],
                          'part_total'=>$value['period'],
                          'pay_day'=>$i,
                          'start_time'=>$startTime,
                          'end_time'=>$endTime,
                          'repayment_time'=>$repayMentTime,
                          'differ_day'=>$differDay,
                          'type'=>$type,
                          'charge_status'=>$repayMentTime>time()?2:1,
                          'begin_date'=>date('Y-m-d',$startTime),
                          'finish_date'=>date('Y-m-d',$endTime),
                          'repayment_date'=>date('Y-m-d',$repayMentTime)
                      ];
                      
                  }
              }
              if($accountData['deserve'] - $accountModel['reduce'] >= 0){
                  $accountData['reduce'] = 0;
                  $accountData['deserve'] -= $accountModel['reduce'];
              }else{
                  $accountData['reduce'] = $accountModel['reduce'] - $accountData['deserve'];
                  $accountData['deserve'] = 0;
              }
              $this->accountList->saveAll($accountListData);
              $this->account->save($accountData,['id'=>$accountData['id']]);
               $model = new PartDetails; 
              try{
                     $model->allowField(true)->saveAll($partData);
                    return true;
              }catch (\Exception $e){
                  Log::record('[ part_details表插入数据 ]'.$e->getMessage(),'error');
                  return false;
              }
          }
    }
   

    
    
    
}

